﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tasker.Common
{
    /// <summary>
    /// String helper functions.
    /// </summary>
    public static class StringHelper
    {
        /// <summary>
        /// Ensures that string is not null.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string EnsureNotNull(this string str)
        {
            return str == null ? string.Empty : str;
        }

        /// <summary>
        /// Converts string to a byte array in UTF8 encoding.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] String2ByteArray(this string data)
        {
            return Encoding.UTF8.GetBytes(data.ToArray());
        }

        /// <summary>
        /// Converts byte array to a string using UTF8 encoding.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ByteArray2String(this byte[] data)
        {
            return Encoding.UTF8.GetString(data);
        }

        /// <summary>
        /// Removes trailing <param name="N"></param> chars.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string RemoveNTrailingChars(this string str, int N)
        {
            if (N != 0)
                return str.Remove(str.Length - N);
            return str;
        }

        /// <summary>
        /// Returns last <param name="N"></param> chars of a given string.
        /// </summary>
        /// <param name="str"></param>
        /// <param name="N"></param>
        /// <returns></returns>
        public static string LastNTrailingChars(this string str, int N)
        {
            if (N == 0)
                return string.Empty;
            return str.Substring(str.Length - N);
        }

        /// <summary>
        /// Returns number of leading whitespace characters.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int GetLeadingWhitespacesCount(this string str)
        {
            int leadingWhitespacesCount = 0;
            while (leadingWhitespacesCount < str.Length && char.IsWhiteSpace(str[leadingWhitespacesCount]))
                leadingWhitespacesCount++;
            return leadingWhitespacesCount;
        }

        /// <summary>
        /// Returns number of trailing whitespace characters.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int GetTrailingWhitespacesCount(this string str)
        {
            int res = str.Length - 1;
            while (res >= 0 && char.IsWhiteSpace(str[res]))
                res--;
            return str.Length - res - 1;
        }

        /// <summary>
        /// Given a string <paramref name="str"/> inserts <paramref name="markerTexts"/> strings at corresponding positions.
        /// Positions are in plain string <paramref name="str"/>.
        /// All positions must be given in non-decreasing order.
        /// </summary>
        /// <param name="str"></param>
        /// <param name="markerTexts"></param>
        /// <returns></returns>
        public static string InsertMarkers(this string str, IEnumerable<Tuple<string, int>> markerTexts)
        {
            int shift = 0;
            string res = str;
            foreach (var marker in markerTexts)	// go from leftmost to rightmost position.
            {
                res = res.Insert(marker.Item2 + shift, marker.Item1);
                shift += marker.Item1.Length;
            }
            return res;
        }

        /// <summary>
        /// Formats <paramref name="format"/> string with the help of string.Format.
        /// </summary>
        /// <param name="format"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string Format(this string format, params object[] args)
        {
            return string.Format(format, args);
        }
    }
}
